package com.young.msg.core;

import com.young.common.core.event.IEventSubscriber;
import com.young.common.util.AssertUtil;
import com.young.common.util.CollectionUtil;
import com.young.common.util.JsonUtil;
import com.young.common.util.StringUtils;
import com.young.interfaces.common.event.model.EventMessage;
import com.young.interfaces.common.event.model.IEvent;
import com.young.msg.model.MailSendCommand;
import com.young.msg.model.MailSenderConfig;
import com.young.msg.model.enums.EMsgEventDefinitionEnum;
import com.young.msg.service.IMsgMailSenderConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 邮件发送控制中心
 *
 * @author wangjy
 * @date 2021/10/29 23:29:55
 */
@Service
public class MailSenderControlCenter implements InitializingBean, IEventSubscriber {
    private static final Logger logger = LoggerFactory.getLogger(MailSenderControlCenter.class);
    /**
     * 默认邮件发送器标识
     */
    private static final String DEFAULT_SENDER_CODE = "default";

    /**
     * 发送器池
     */
    private static final Map<String, YoungJavaMailSender> JAVA_MAIL_SENDER_MAP = new HashMap<>();

    /**
     * 邮件发送配置
     */
    @Autowired
    private IMsgMailSenderConfigService mailSenderConfigService;

    // 初始化邮件发送配置
    @Override
    public void afterPropertiesSet() throws Exception {
        logger.info("[邮件发送控制中心] 初始化开始.");
        // 查询所有有效邮箱配置
        List<MailSenderConfig> mailSenderList = mailSenderConfigService.getValidMailConfigList();
        if (CollectionUtil.isNotEmpty(mailSenderList)) {
            for (MailSenderConfig mailConfig : mailSenderList) {
                // 构建发送器
                YoungJavaMailSender sender = YoungJavaMailSender.newInstance(mailConfig);
                // 设置发送器
                putSender(sender);
            }
        }
        logger.info("[邮件发送控制中心] 初始化完成.");
    }

    /**
     * 添加/更新邮件发送器
     *
     * @param sender
     */
    private static void putSender(YoungJavaMailSender sender) {
        if (!sender.check()) {
            logger.warn("[邮件发送控制中心-设置发送器] 该邮箱发送器无效,标识={},邮箱账号={}", sender.getSenderCode(), sender.getUsername());
            return;
        }
        JAVA_MAIL_SENDER_MAP.put(sender.getSenderCode(), sender);
        logger.info("[邮件发送控制中心-设置发送器] 装载邮件发送器,标识={},邮箱账号={}", sender.getSenderCode(), sender.getUsername());
    }

    /**
     * 移除发送器
     * @param senderCode
     */
    private static void removeSender(String senderCode) {
        YoungJavaMailSender sender = JAVA_MAIL_SENDER_MAP.remove(senderCode);
        if (sender != null) {
            logger.warn("[邮件发送控制中心-移除发送器] 移除邮件发送器,标识={},邮箱账号={}", sender.getSenderCode(), sender.getUsername());
        }
    }

    /**
     * 发送邮件
     *
     * @param mailSendCommand
     */
    public static void send(MailSendCommand mailSendCommand) {
        AssertUtil.notBlank(mailSendCommand.getReceiver(), "收件人邮箱不允许为空");
        AssertUtil.notBlank(mailSendCommand.getTitle(), "邮件标题不允许为空");
        AssertUtil.notBlank(mailSendCommand.getContent(), "邮件内容不允许为空");

        // 获取发送器
        YoungJavaMailSender sender = getSender(mailSendCommand);
        AssertUtil.notNull(sender, "匹配邮件发送器失败");

        // 构建邮件消息对象
        SimpleMailMessage message = buildMailMessage(mailSendCommand, sender);

        // 发送
        sender.send(message);
    }

    /**
     * 构造邮件消息
     *
     * @param mailSendCommand
     * @param sender
     * @return
     */
    public static SimpleMailMessage buildMailMessage(MailSendCommand mailSendCommand, YoungJavaMailSender sender) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(String.format("%s<%s>", sender.getFromName(), sender.getUsername()));
        message.setTo(mailSendCommand.getReceiver());
        message.setSubject(mailSendCommand.getTitle());
        message.setText(mailSendCommand.getContent());
        return message;
    }

    /**
     * 获取发送器
     *
     * @param mailSendCommand
     * @return
     */
    private static YoungJavaMailSender getSender(MailSendCommand mailSendCommand) {
        if (CollectionUtil.isEmpty(JAVA_MAIL_SENDER_MAP)) {
            return null;
        }
        if (StringUtils.isNotBlank(mailSendCommand.getSenderCode())) {
            return JAVA_MAIL_SENDER_MAP.get(mailSendCommand.getSenderCode());
        }
        return JAVA_MAIL_SENDER_MAP.get(DEFAULT_SENDER_CODE);
    }


    /**
     * 订阅者名字
     *
     * @return
     */
    @Override
    public String name() {
        return this.getClass().getSimpleName();
    }

    /**
     * 订阅的事件
     *
     * @return 订阅的事件
     */
    @Override
    public IEvent[] events() {
        return new EMsgEventDefinitionEnum[]{EMsgEventDefinitionEnum.MAIL_ADD, EMsgEventDefinitionEnum.MAIL_UPDATE, EMsgEventDefinitionEnum.MAIL_DELETE};
    }

    /**
     * 事件处理
     *
     * @param message 事件消息
     */
    @Override
    public void process(EventMessage message) {
        logger.info("[邮件发送控制中心] 收到到邮箱变更事件={}", JsonUtil.toJson(message));
        if (EMsgEventDefinitionEnum.MAIL_ADD == message.getEvent() || EMsgEventDefinitionEnum.MAIL_UPDATE == message.getEvent()) {
            String code = (String) message.getData();
            // 先移除
            removeSender(code);
            // 查询邮箱配置
            MailSenderConfig mailSenderConfig = mailSenderConfigService.getBySenderCode(code);
            if (mailSenderConfig != null && mailSenderConfig.dataValid()) {
                YoungJavaMailSender sender = YoungJavaMailSender.newInstance(mailSenderConfig);
                // 再设置
                putSender(sender);
            }
        } else if (EMsgEventDefinitionEnum.MAIL_DELETE == message.getEvent()) {
            String code = (String) message.getData();
            // 移除
            removeSender(code);
        }
    }
}
